/*
   Copyright (c) 2016 Intel Corporation.  All rights reserved.
   See the bottom of this file for the license terms.
*/




#include "CurieTimerOne.h"
#include <CurieBLE.h>
//#define IR_send 0x89
boolean sendsuccess = false;
long lasttime = 0;
byte moveblink = 0;
int safetime = 100;
int tag_finish_key1, tag_finish_key2;
int last_key_state1, last_key_state2;
int last_event;
#define gpioindex 8
#define gpioreseive 6
#define DELYA_0 320
#define DELAY_1 600
#define INFRARED_SEND_STATUS_ON 1
#define INFRARED_SEND_STATUS_OFF 0
#define MDrv_GPIO_Set_Low( u8IndexGPIO) digitalWrite(u8IndexGPIO, LOW)
#define MDrv_GPIO_Set_High( u8IndexGPIO) digitalWrite(u8IndexGPIO, HIGH)
long blink_timmer;
boolean free_one = false, free_two = false;
int bt = 500;
void setup()
{
  pinMode(13, OUTPUT);
  pinMode(gpioreseive, INPUT);
  CurieTimerOne.pwmStart(gpioindex, 50.0, 25);//38K
  //CurieTimerOne.pwmStart(13, 50.0, 25);//38K
  digitalWrite(gpioindex, LOW);

  CurieTimerOne.pause();
  // Serial.begin(9600);

  // initialize the BLE hardware
  BLE.begin();

  // Serial.println("BLE Central - SensorTag button");
  // Serial.println("Make sure to turn on the device.");

  // start scanning for peripheral
  BLE.scan();
}

void loop()
{
  // check if a peripheral has been discovered
  BLEDevice peripheral = BLE.available();

  if (peripheral)
  {
    if (peripheral.localName() == "DragonBone")
    {
      // stop scanning
      BLE.stopScan();

      Test_process(peripheral);

      // peripheral disconnected, start scanning again
      digitalWrite(13, LOW);
      bt = 500;
      BLE.scan();
    }
  }
  else
  //BLE.scan()
  ;
}

void Test_process(BLEDevice peripheral)
{
  // connect to the peripheral
  // Serial.println("Connecting ...");
  if (peripheral.connect())
  {
    // Serial.println("Connected");
  }
  else
  {
    // Serial.println("Failed to connect!");
    return;
  }

  // discover peripheral attributes
  // Serial.println("Discovering attributes of service 0xfff0 ...");
  
  if (peripheral.discoverAttributesByService("fff0"))
  {
    // Serial.println("Attributes discovered");
  }
  else
  {
    // Serial.println("Attribute discovery failed.");
    peripheral.disconnect();
    return;
  }

  // retrieve notify characteristics
  BLECharacteristic simpleKeyCharacteristic = peripheral.characteristic("ff03");
  BLECharacteristic IR_receive_Characteristic = peripheral.characteristic("ff07");
  BLECharacteristic SecurityIC_Characteristic = peripheral.characteristic("ff08");
  // retrieve write characteristics
  BLECharacteristic writeCharacteristic = peripheral.characteristic("ff02");


  delay(safetime);
  // Serial.println("");
  //ff07
  // Serial.println("Subscribing to IR_receive_Characteristic ff07 ...");
  if (!IR_receive_Characteristic)
  {
    // Serial.println("no IR_receive_Characteristic found!");
    peripheral.disconnect();
    return;
  }
  else if (!IR_receive_Characteristic.canSubscribe())
  {
    // Serial.println("IR_receive_Characteristic is not subscribable!");
    peripheral.disconnect();
    return;
  }
  else if (!IR_receive_Characteristic.subscribe())
  {
    // Serial.println("subscription failed!");
    peripheral.disconnect();
    return;
  }
  else
  {
    // Serial.println("ff07 Subscribed successfull");
    // Serial.println("Listen IR data from anather DragonBone.");

  }
  
    delay(safetime);
    // Serial.println("");
    // // subscribe ff03
    // Serial.println("Subscribing to FF03 characteristic ...");
    if (!simpleKeyCharacteristic)
    {
    // Serial.println("no FF03 characteristic found!");
    peripheral.disconnect();
    return;
    }
    else if (!simpleKeyCharacteristic.canSubscribe())
    {
    // Serial.println("FF03 characteristic is not subscribable!");
    peripheral.disconnect();
    return;
    }
    else if (!simpleKeyCharacteristic.subscribe())
    {
    // Serial.println("subscription failed!");
    peripheral.disconnect();
    return;
    }
    else
    {
    // Serial.println("ff03 Subscribed successfull");
    // Serial.println("Press button1 and button2 on DragonBone.");
    }
    delay(safetime);
  
  while (peripheral.connected())
  {

    if (millis() - blink_timmer >= bt)
    {
      static int i;
      i = !i;
      blink_timmer = millis();
      digitalWrite(13, i);
      moveblink = ~moveblink;
    }
    //Curie receive ir date info
    byte rec = YC_IR_CheckStart();
    if (rec != 0 && rec != 0XFF && rec == 0x72)
    {
      // Serial.print("got IR data from DragonBone :");
      // Serial.print(rec);
      // Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!!");
      free_one = true;
      bt = 100;
    }
    //DragonBone ir receive data info
    if (IR_receive_Characteristic.valueUpdated())
    {
      // Serial.println(IR_receive_Characteristic.value()[0], HEX);
      if (IR_receive_Characteristic.value()[0] == 0x88)
      {
        // Serial.println("IR_TESTE successfull............................................................................");
        sendsuccess = true;
        //peripheral.disconnect();
        free_two = true;
        bt = 100;
      }
      else
        ;// Serial.println("IR_TESTE with wrong message......");
    }

    if (free_one == true && free_two == true)
    {
      peripheral.disconnect();
      free_one = false;
      free_two  = false;
      
      //      delay(safetime);
      return;
    }
    //ff03 update message
    if (simpleKeyCharacteristic.valueUpdated())
    {
      byte head[2];
      byte realPluse[2];
      byte keys[2];
      byte voltage[2];
      byte deltaPluse;
      byte event;
      byte caculatedValue[2];
      int index;
      byte ff03_meg[12];
      memcpy(ff03_meg, simpleKeyCharacteristic.value(), 12);



      int num_pluse = ff03_meg[10] + ff03_meg[11] * 256;
      int vol = ff03_meg[6] + ff03_meg[7] * 256;
      if (num_pluse >= 65500)
      {
        num_pluse = 0;
      }

      // Serial.print("Now PUSHING ...");
      // Serial.println(num_pluse);


      //detect key0 release;
      if (ff03_meg[4] == 0x01 && last_key_state1 == 0x00)
      {
        byte user_data1[6] = {0xf0, 0x55, 0x03, 0xe3, 0x51, 0x72};
        // first bit corresponds to the right button
        // Serial.println("DOWN button pressed");
        tag_finish_key1 = 1;
        // Serial.println("Try send ir from DragonBone ready go !!!!!!!!!!!! ");
        writeCharacteristic.write(user_data1, 6);
        // Serial.println(" Cmd send ok............");
      }
      //detect key1 release;
      if (ff03_meg[5] == 0x01 && last_key_state2 == 0x00)
      {
        // second bit corresponds to the left button
        // Serial.println("UP button pressed");
        tag_finish_key2 = 1;
        // Serial.println("ready  to send IR message 0x88");
        Infrared_Send_Status(INFRARED_SEND_STATUS_ON);//
        delayus(4000);//
        IR_send(0x88);
        // Serial.println("Send out finish");
      }

      last_event = ff03_meg[9];
      //two keys all released ok
      if (tag_finish_key1 == 1 && tag_finish_key2 == 1)
      {
        tag_finish_key1 = 0;
        tag_finish_key2 = 0;
        // Serial.println("ready  to send IR message 0x88");
        Infrared_Send_Status(INFRARED_SEND_STATUS_ON);//¿ªÊ¼ÔØ²¨
        delayus(4000);//ÆðÊ¼4msµÄ38kÔØ²¨±ãÓÚÈÃºìÍâ½ÓÊÕÍ·Ê¶±ðµ½ÐÅºÅ
        IR_send(0x88);
        // Serial.println("Send out finish");
      }
      last_key_state1 = ff03_meg[4];
      last_key_state2 = ff03_meg[5];
    }
  }

  // Serial.println("DragenBone disconnected!");

}

void delayus(int us_time)
{
  delayTicks(32 * us_time);
}

void Infrared_Send_Status(boolean state)
{
  if (state == INFRARED_SEND_STATUS_OFF)
  {
    //YC_PWMCloseChanel(3);
    CurieTimerOne.pause();
    digitalWrite(gpioindex, LOW);
  }
  if (state == INFRARED_SEND_STATUS_ON)
  {
    //YC_PWMOpenChanel((YC_PWMChanel_e)0,3);
    CurieTimerOne.resume();
  }
}
void IR_send(byte data)
{
  byte i;

  for (i = 0; i < 8; ++i)
  {
    if (data & 0x80)
    {
      Infrared_Send_Status(INFRARED_SEND_STATUS_OFF);
      delayus(DELYA_0);
      Infrared_Send_Status(INFRARED_SEND_STATUS_ON);
      delayus(DELAY_1);
    }
    else
    {
      Infrared_Send_Status(INFRARED_SEND_STATUS_OFF);
      delayus(DELYA_0);
      Infrared_Send_Status(INFRARED_SEND_STATUS_ON);
      delayus(DELYA_0);
    }
    data <<= 1;
  }
  Infrared_Send_Status(INFRARED_SEND_STATUS_OFF);
}
byte YC_IR_CheckStart(void)
{
  byte YC_IRReceiveData;
  if (digitalRead(gpioreseive) == LOW)
  {
    delayus(2000);
    if (digitalRead(gpioreseive) != LOW)   //if high,this is  interference signal
    {
      return 0;
    }
    else
    {
      while (digitalRead(gpioreseive) == LOW); // wait until the low signal end
      YC_IRReceiveData = YC_IR_GetCode();
      //BT_BleSendData(&YC_IRReceiveData, 1, BLE_TX_HANDLE_FF07);
    }
  }
  return YC_IRReceiveData;
}

byte YC_IR_GetCode(void)
{
  byte BitCount, temp = 0;

  for (BitCount = 0; BitCount < 8; BitCount++)
  {
    temp <<= 1;
    while (digitalRead(gpioreseive) != LOW); //wait until the high signal end
    delayus(440);
    if (digitalRead(gpioreseive) == LOW) //
    {
      temp |= 0x01;       //bit1
      while (digitalRead(gpioreseive) == LOW); //wait until the low signal end
    }
  }
  return temp;
}
